\section Creating and Editing Forms

\grok\ distinguishes databases and forms. A database is an array of
unformatted data, while the form specifies the structure of the data
and describes how to display it in a card. The standard user interface
that comes up when \grok\ is started deals with database presentation and
modification; to edit the presentation, or to create a new database,
start the form editor from the File pulldown in the main window.

The form editor is a separate window that is rather more complicated
than the standard database user interface. It is basically a simple
UI builder that allows the user to create and position UI elements in
a card.

\subsection General Setup

The first step when creating a new database is choosing a form name.
This is the name that will appear in the Database pulldown in the main
window (actually, the pulldown should be called Form, but I fear that
would confuse casual users). Every form references a database whose
contents it presents; this name must also be chosen. Typically, both
names are the same.

Both the form name and database names are also the file names the
form and the database will be stored in. The form name gets the
extension ``.gf'', and non-procedural databases get the extension ``.db''
tacked on if the names are not fully qualified (i.e., do not begin with
``/'' or ``$\sim$''). If the database is procedural, the database file is a
script, and has no .db or any other extension. This script is executed
to read or write data.

When a database or form is read, the path it was read from is stored;
when the database or form is changed, it is written back to that path.
When a new database is created, and its name does not begin with ``/''
or ``$\sim$''  as defined in the second line of the form editor, it is stored in
the same directory as its form file. The default is always $\sim$/.grok.
The Help$\rightarrow$Database popup shows which paths are actually used.

The database is a two-dimensional array of strings. The rows are called
{\it cards}, and the columns are called {\it fields}. Rows are separated
by newlines, and columns are separated by the field delimiter. The field
delimiter is a colon by default, but can be changed to any character.
The button accepts characters, octal constants {\it $\backslash$nnn}, and
the tab character {\tt $\backslash$t}. Any character other than {\it
$\backslash$0} and newline can be chosen; \grok\ will properly escape the
character when it appears in a database string. Severe chaos may result
if the delimiter character is changed when the database already contains
data.

Databases can be marked read-only. A user accessing a database through
a form that is has the read-only flag set will not be able to change any
cards, and will not be able to write back.

A procedural database does not read a file, but calls a script that
provides the data in the same format that the file would contain. If
the {\tt procedural} button is turned on, the referenced database name
is the name of the script, not of any database file. It may contain
options. When the database is read, \grok\ appends the option {\tt "-r"}
(read) and the form name as shown in the {\tt Form name} button (without
prepending a path or appending an extension). When writing, {\tt -w} is
appended instead of {\tt -r}. The script must print the data to stdout
if {\tt -r} is specified, or must accept the data from stdin if {\tt -w}
is specified, separating columns with the field delimiter character and
separating rows with newlines. If the delimiter or newlines appear in
as part of a data string, it must be escaped with a backslash.

A comment can be specified that should give the name of the author of
the form, or special caveats. The comment is displayed only in the form
editor window.

\subsection Creating a Card

After the general setup is done, fields can be arranged on a card ``canvas'',
which has the same size and layout as the final card will have, but
doesn't look as nice and shows extra information. Fields appear as blue
rectangular boxes, some of which are divided in the middle (depending on
the field type). The current field, whose specification is displayed in
the form editor window. A field can be moved by left-clicking somewhere
inside the field (but not too close to an edge) and dragging. The size
can be changed by dragging one of the four edges, and the divider can also
be dragged. Fields should not overlap. The card canvas can be resized;
fields should not overlap the canvas window edges.

The canvas is divided in two parts by a horizontal fat line. The divider
can be moved vertically by dragging the little square that initially
appears near the top right corner of the canvas. Everything above the
divider is the {\it static part}; everything below the divider is the
{\it card part}. The card part displays one row of the database if one
is selected; this information changes frequently whenever a search is
performed or a row is chosen from the summary.

The static part does not normally change, it is intended for static data
such as the average of all fields, a chart displaying statistics, or
buttons. This part is not entirely static because entering new cards
or resorting the database may change data, but it is not bound to a
particular card, and it remains accessible if no card is chosen. This
makes it a good place to place form switch buttons that would otherwise
become unavailable when no card is displayed.

There are several types of fields. Not all of them store data in the
database; some are decorative or display computed information.

\itmindent=2cm
\itm{\bf Input}
This is the main type of field. It displays an editable (unless turned
off) string in the database, along with a label.
Input fields should not be put into the static part of the canvas.

\itm{\bf Time}
A variation of the Input field. The database representation is a number
of seconds. It is displayed as a date, as a time, as both date and time,
and as a duration. The first three assume the database string to be a
number of seconds since January 1, 1970; the last simply assumes a
number of seconds up to 86399 (one day minus 1 second). When a string
is entered into a Time field, it is converted to the numeric representation,
reformatted, and reprinted. Time fields are useful because they can be
used in expressions for calculation; expressions always see the numeric
database string.
Time fields should not be put into the static part of the canvas.

\itm{\bf Note}
A note is a multi-line Input field. It should be used only for multiline
text input because it cannot be tabbed over, and because pressing Return
when entering data into the card into a Note actually inserts a newline,
rather than skipping to the next field as an Input-type field would.
Note fields should not be put into the static part of the canvas.

\itm{\bf Choice}
Unlike all other types, many choice fields reference the same database
string. They all must have the same summary column, the same database
column, and the same internal field name (these three are buttons in the
form editor). They differ only in the Choice/flag code. \grok\ always makes
sure that only one of the choice fields with identical internal field names
can be active at any time; the database string then matches the Choice/flag
code of that field. Most attributes of a {\tt Choice} item, when changed,
are copied to all other {\tt Choice} items that have the same internal name.
Choice fields should not be put into the static part of the canvas.

\itm{\bf Label}
Labels are purely decorative. They print an arbitrary one-line string at
a position in the card. There is no associated database string. Labels
are rarely needed because most of the other types come with their own
built-in label parts. The label is static, expressions cannot be used.

\itm{\bf Print}
Print fields are like Input fields, but no text can be entered. Unlike
labels, they can display an expression specified in the Input Default
button of the form editor. This can be used to display a running average
or sum in cards, or display other computed information. There is no
associated database string. Print fields are useful in both the static
and card parts of the canvas.

\itm{\bf Flag}
Flags are boolean database strings: the string either matches the
predefined string ({\it true}), or it is empty ({\it false}). (In fact,
a string that doesn't match is also considered {\it false}, but this is
not part of the normal operation.) The string that constitutes {\it true}
is specified with the Choice/flag code button in the form editor.

\itm{\bf Button}
Buttons have an associated action expression that is executed when the
button is pressed. This action could start a shell script, for example.
Buttons are not associated with any database string, but the expression
can access one. For example, a database of demo programs can have a
button that executes the program. The returned string is executed, there
is no need to use the {\tt system} keyword unless nesting is desired. Note
that the action expression is the only type of expression that may
contain {\tt switch} statements; see the Expression Grammar chapter for
details. It is often a good idea to put buttons in the static part of
the canvas.

\itm{\bf Chart}
Charts display data as bar or line charts. The X axis is divided into
one slot per row in the database; the Y axis depends on the values
computed from those rows (X and Y may be exchanged). Each chart contains
one or more {\it components}. A component computes values that is plotted
in the chart; a chart may display more than one value. For example, an
expense account chart may display a stacked bar chart consisting of
different color-coded types of costs, each described by a component.
There are many variations for configuring charts and their components.
Charts should be put into the static part of the canvas.

\itmindent=2em
Each field has a number of parameters that depend on the type. The most
important is the internal field name. It must be unique, except for choice
fields which are grouped by assigning common internal field names. If
the field references a database string, the internal field name also
names the database string. The internal field name can be used in
expressions to read the database string. For example, suppose you have a
database of backup tapes, you may have an {\tt Input} field with an
internal field name {\it capacity}, and another {\tt Input} field named
{\it used}. You could then add a {\tt Print} field whose Input Default
expression is {\tt (\_capacity~-~\_used)}. The {\tt Print} field then
displays the remaining free space on each tape, even though the database
only contains total capacity and used capacity. Another {\tt Print}
label may have an expression {\tt (sum(\_used))}, which displays a running
total of all tapes' contents. {\tt sum} is one of a group of functions
that loop over all cards rather than just referencing the current card;
see the Expression Grammar chapter for details. It is also possible to
reference a database field for which there is no field description in
an expression; in this case, the field is referenced by number. Fields
in the database are numbered left to right, beginning with 0.

The next button in the form editor is the database column. It needs to
be specified only for field types that display the column and allow
entry into the column. These fields are ``windows'' into the database;
there is normally one field for each database column. All fields that
do not reference a database column are merely decoration, no change of
the database is possible through such a decorative field (although the
decorative field may read the database, as {\tt Print} fields do). This
relation between fields and database columns also serves to give a
symbolic name to database columns; these symbolic names can be used in
expressions by prefixing them with an underscore. (It is also possible
to use the column number in expressions, but that is less convenient).

The main window has three parts, a summary, the static area, and the
card.  The summary contains one line per card, while the card contains
the entire card's information as defined with the form editor and the
card canvas. The static part is optional and programmed in the same way
as the card. The Summary column and Width in summary buttons in the
form editor determine which fields also appear in the summary; this is
a subset of the fields that reference a database column (decoration
fields can not be put into the summary).  The two buttons specify the
order in database column and the width in characters. Two blanks are
inserted between fields in the summary automatically. The summary has a
title; it can not be specified directly but is taken from the Label
text of the field.

Here is a brief summary of all buttons in the form editor that specify
a field in the card:

\itmindent=5cm
\medskip
\itm{\bf Field type}
The type of a field is entered here. See above for a list of available
types and what they do.

\itm{\bf Searchable}
The main window contains a Search input button. It searches through all
cards and puts all cards containing the search string into the summary.
Fields that are not searchable are excluded from the search.

\itm{\bf Read only}
The user cannot change the database string referenced by a field that
is read-only. This is useful if there are two forms referencing the
same database, one for you and one for the unwashed masses with lots
of read-only flags set. The read-only flag can also be set for the
entire database with the button near the top of the form editor window;
setting that flag overrides all field read-only flags.

\itm{\bf Not sortable}
The field will be omitted from the Sort pulldown in the main menu.

\itm{\bf Default sort}
When the file is read in from disk, it is sorted by the field that has
this flag on. Setting it in any field will clear the Default sort flag
in all other items automatically. If no field has the Default sort flag,
the file will not be sorted when it is read. It is possible but not
recommended to have both the Default sort flag and the Not sortable flag
on in the same field.

\itm{\bf Internal field name}
All fields have an unique name. Choice names are not unique, choice fields
are grouped by a common name. If the field references a database string,
the internal field name also names the database column, which can then
be accessed in expressions symbolically.

\itm{\bf Database column}
If the field references a database column, this button says which one,
0 being the first column. If not, this button is grayed out. The column
number must be unique, except for choice fields which are grouped by
a common database column (and a common internal field name, too).

\itm{\bf Width in summary}
If the width is nonzero, the database string referenced by the field will
appear in the summary, with as many characters as specified. Two blanks
are appended. The summary always uses monospaced Courier to make columns
line up vertically.

\itm{\bf Summary column}
If the width is nonzero, this value specifies the order of fields in
summary lines. No two fields may have the same summary column number,
but there may be gaps.

\itm{\bf Choice/flag code}
The string that Flag and Choice fields store in the database, if active.
No two Choice fields with the same internal name may have the same code.

\itm{\bf Shown as}
If this string is set, it will be displayed in the summary in place of the
choice/flag code. Basically, it is a mnemonic name for the choice/flag
code that a user can understand.

\itm{\bf Time format}
Time fields have four different formats, as described above. The format
controls what gets printed into the card, and how user input is interpreted.

\itm{\bf Label text}
All field types come with some kind of text string that is printed into
the field in the card. This string is always literal, it cannot be an
expression.

\itm{\bf Label justification}
Labels can be centered, left-aligned, or right-aligned. This is not
shown in the card canvas, press the Preview button to see the effect.

\itm{\bf Label font}
The font used for the label. Five fonts are available.

\itm{\bf Max input length}
The maximum number of characters than can be entered into an Input, Time,
or Note field. The default is 100 for Input and Time fields, and 10000
for Note fields. Always make sure that note fields have a sufficient
maximum length. This number is passed to the Motif widget to limit
input length, but does not lead to increased memory usage for the
database.

\itm{\bf Input default}
For Input, Time, Flag, and Choice fields, this field provides the defaults
when a new card is added to the database. It can be an expression. For
Print fields, the Input default specifies what gets printed into the inset
area of the field; input default is actually a misnomer because Print
field texts cannot be input and are evaluated whenever the database changes,
not just when a new card is added. In general, Choice fields should always
have a default. If the field has type Time, the input default expression
should evaluate to a number of seconds, not to a string containing
a date. For example, to make the Time field default to today, use
(date), not {date}.

\itm{\bf Input justification}
Input can be centered, left-aligned, or right-aligned. This is not
shown in the card canvas, press the Preview button to see the effect.

\itm{\bf Input font}
The font used for the input area. Five fonts are available. It is recommended
to use Courier for Note fields (and, by extension, for Input and Time
fields) because printing functions print notes using a fixed-width font.

\itm{\bf Grayed out if}
If the named expression evaluates to {\it true}, the field is grayed
out and cannot be used to alter the database. The expression is evaluated
every time the database changes.

\itm{\bf Invisible if}
If the named expression evaluates to {\it true}, the field is excluded
from the card. The expression is evaluated only once, when the database
is read from disk. This can be used to hide entries if the wrong user
has read the database. Invisibility does not affect the summary.

\itm{\bf Read-only if}
If the named expression evaluates to {\it true}, the field is read-only.
The expression is evaluated only once, when the database is read from
disk.

\itm{\bf Skip if}
Normally, pressing Return in an Input or Time field advances the cursor
to the next field (fields are ordered by their bottom left corner, in
Y-major order). If the named expression of the next field evaluates to
{\it true}, the field is skipped and the cursor is put elsewhere. This
expression is evaluated every time return is pressed in the previous field.
A constant expression such as {\tt true} is also useful.

\itm{\bf Action when pressed}
If the button is pressed, this expression is evaluated. The result is
ignored. Typically, the expression is the name of a shell script. The
expression may use the {\tt switch} statement, which switches to another
database and/or performs a query on all cards.

%%% \itm{\bf Action when added}
%%% This button is not used yet.
%%% \itmindent=2em
%%% \medskip

\itm{\bf Chart flags}
Not documented yet. This part of the menu is still under development.
%<<<
\itmindent=2em
\medskip

Some of the above accept expressions. An expression begins with a
parenthesis, a brace, or a dollar sign. Everything else is a literal
string. Parentheses and braces are numeric and string expressions,
respectively; a dollar sign followed by an environment variable is a
shortcut for the same sequence enclosed in braces. The {\tt system}
statement should be used sparingly, because some expressions (such
as the grayed-out-if expression) are evaluated frequently. See the
Expression Grammar section for details.

\subsection Buttons

There is a row of buttons in the form editor for various operations:

\itmindent=2.5cm
\itm{\bf Queries}
Starts up a window that allows entry of standard queries, as name/expression
pairs. The name is what will appear in the Query pulldown in the main menu;
the expression is what gets executed if the name is selected in the pulldown.
When a name is selected, the expression is applied to all cards in the
database, and those that return {\it true} are put into the summary. For
example, assuming your database has an Input field with the internal name
{\tt value}, the query expression {\tt (\_value\ \>\ avg(\_value))} will
select all cards whose value is above average.One of the queries can
be selected as the default query that will be performed when the database
is read from disk.

\itm{\bf Def Help}
The main window has a help button in the lower left corner. This button
pops up a help window with some generic info about \grok. With the Def
Help button, more text can be entered that will be appended to the generic
help text. The text should explain the card, how to use it, and what the
fields mean.

\itm{\bf Debug}
This button checks the consistency of all fields, and reports conflicts
such as non-unique internal names or redundant choice flags. At this time,
expressions are not checked. If the Debug button reportrs nothing, the
no problems were found. The Done button always does a debugging run first,
and refuses to exit if errors were found.

\itm{\bf Preview}
The card canvas shows the layout of fields in the card, as boxes that
show additional information such as type, database column, flag/choice
code, and summary column. This does not reflect the final card that the
user will see very well; in particular, whether a label string fits into
the field on the card canvas does not mean that the same label will fit
into the final card. Preview shows precisely what the card will look like.

\itm{\bf Help}
Print general help information.

\itm{\bf Cancel}
Discards all operations done with the form editor since it was installed,
and removes the form editor window after asking for confirmation.

\itm{\bf Done}
Check all fields for consistency. If no problems are found, the form file
is written. The file name is taken from the Form name button at the top
of the form, with {\tt $\sim$/.grok} prepended and {\tt .gf} appended if
appropriate.

\itm{\bf Add}
Adds a new field to the card. Its type, parameters, and position on the
card canvas are chosen based on the currently selected card, so it's a
good idea to select a field that is similar to the new one before pressing
Add. If the card canvas has no free space below the bottom field, the new
field may be placed under the bottom field where it can't be seen; it is
generally a good idea to start with a card canvas that is too large and
resize it to the correct size after all fields have been added and positioned.

\itm{\bf Delete}
Delete the currently selected field. There is no Undo function to get it
back.
\itmindent=2em
